﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace NetDh.TestService
{
    /// <summary>
    /// 获取Service对象帮助类
    /// </summary>
    public class ServiceFactory
    {
        private static readonly ConcurrentDictionary<Type, BaseService> _services = new ConcurrentDictionary<Type, BaseService>();

        static ServiceFactory()
        {
            //默认添加本程序集Service
            var types = Assembly.GetExecutingAssembly().GetTypes();
            var baseType = typeof(BaseService);
            foreach (var type in types)
            {
                if (type.IsSubclassOf(baseType))
                {
                    //不会实例化服务对象。只有用到时才会实例化
                    _services.TryAdd(type, null);
                }
            }
        }

        /// <summary>
        /// 获取服务，T一定是继承自BaseService
        /// </summary>
        /// <typeparam name="T">BaseService子类</typeparam>
        /// <returns></returns>
        public static T Get<T>() where T : BaseService
        {
            Type type = typeof(T);
            BaseService service;
            if (!_services.TryGetValue(type, out service))
            {
                throw new Exception("This service cannot be found");
            }
            if (service == null)
            {
                service = Activator.CreateInstance(type) as BaseService;
                _services[type] = service;
            }
            return (T)service;
        }

        /// <summary>
        /// 添加二次开发Service程序集
        /// </summary>
        /// <param name="assembly"></param>
        public static void AddSecondaryAssembly(Assembly secondaryAssembly)
        {
            if (secondaryAssembly == null) return;

            var secTypes = secondaryAssembly.GetTypes();
            var baseType = typeof(BaseService);
            foreach (var secType in secTypes)
            {
                if (secType.IsSubclassOf(baseType))
                {
                    Type parentType = null;
                    foreach (var type in _services.Keys)
                    {
                        if (secType.IsSubclassOf(type))
                        {
                            parentType = type;
                            break;
                        }
                    }
                    if (parentType != null)
                    {//如果二次开发重写了原Service类
                        //优先使用二次开发的Service对象。需要在初始化时就实例化。
                        _services[parentType] = Activator.CreateInstance(secType) as BaseService;
                    }
                    else
                    {//如果二次开发的Service类是新增的，则直接添加，使用时再实例化
                        _services.TryAdd(secType, null);
                    }
                }
            }
        }

    }
}

